# main.py - 修复后的主程序

import sys
import os
import base64
import json
import datetime
import requests
from PyQt5.QtWidgets import (QApplication, QMainWindow, QTabWidget, QWidget, QVBoxLayout,
                             QHBoxLayout, QPushButton, QFileDialog, QLabel, QLineEdit,
                             QDateEdit, QTableWidget, QTableWidgetItem, QHeaderView,
                             QMessageBox, QSplitter, QFrame, QProgressBar, QGroupBox,
                             QFormLayout, QComboBox)
from PyQt5.QtGui import QPixmap, QFont, QIcon, QColor, QPalette
from PyQt5.QtCore import Qt, QDate, QSize, QTimer

from PyQt5.QtCore import QThread, pyqtSignal

# import mysql.connector
# from mysql.connector import Error

import pymysql
from pymysql.err import MySQLError as Error

import logging
logging.basicConfig(level=logging.INFO)

# 数据库配置
DB_CONFIG = {
    'host': '127.0.0.1',         # 使用 IP 地址
    'user': 'root',
    'password': 'root',
    'database': 'invoice_system',
    'connect_timeout': 5      # 设置连接超时，防止长时间阻塞
}
# 百度OCR API配置
OCR_API_URL = "https://aip.baidubce.com/rest/2.0/ocr/v1/vat_invoice"
OCR_API_TOKEN = "24.fb0e6430b275dca6033c8b6e9b5b0166.2592000.1744450324.282335-118025493"  # 修改为你的token


class InvoiceSystem(QMainWindow):
    def __init__(self):
        super().__init__()
        print("初始化主窗口")
        self.init_ui()
        print("UI初始化完成")

        # 延迟建立数据库连接
        QTimer.singleShot(0, self.init_db)

    def init_db(self):
        try:
            # 连接数据库
            logging.info("尝试连接数据库...")
            sys.stdout.flush()
            self.conn = pymysql.connect(**DB_CONFIG)
            self.cursor = self.conn.cursor()
            logging.info("尝试创建表...")
            sys.stdout.flush()
            self.cursor.execute('''
                CREATE TABLE IF NOT EXISTS invoices (
                    id INT AUTO_INCREMENT PRIMARY KEY,
                    invoice_number VARCHAR(50) UNIQUE,
                    invoice_date DATE,
                    seller_name VARCHAR(100),
                    purchaser_name VARCHAR(100),
                    item_name VARCHAR(100),
                    amount_without_tax DECIMAL(10, 2),
                    tax DECIMAL(10, 2),
                    amount_with_tax DECIMAL(10, 2),
                    image_path VARCHAR(255),
                    upload_date DATETIME DEFAULT CURRENT_TIMESTAMP
                )
            ''')
            self.conn.commit()


            # 关键：在成功创建表后标记数据库已连接
            self.db_connected = True
            print("表创建成功，数据库已连接！")

        except Error as e:
            print(f"数据库错误: {str(e)}")
            # 如果发生错误，可以标记为未连接
            self.db_connected = False
            QMessageBox.critical(self, "数据库错误", f"连接数据库时出错: {e}")
            raise

    def init_ui(self):
        # 设置窗口属性
        self.setWindowTitle("发票管理系统")
        self.setGeometry(100, 100, 1200, 800)

        # 初始化一些必要的变量
        self.invoice_images = {}

        # 设置全局样式
        self.set_style()

        # 创建主布局
        main_widget = QWidget()
        main_layout = QVBoxLayout()
        main_widget.setLayout(main_layout)
        self.setCentralWidget(main_widget)

        # 创建标签页
        tabs = QTabWidget()
        tabs.setFont(QFont("Arial", 11))

        # 上传页面
        upload_tab = QWidget()
        tabs.addTab(upload_tab, "发票上传")

        # 查询页面
        query_tab = QWidget()
        tabs.addTab(query_tab, "发票查询")

        # 统计页面
        stats_tab = QWidget()
        tabs.addTab(stats_tab, "发票统计")

        # 添加标签页到主布局
        main_layout.addWidget(tabs)

        # 设置各个标签页的内容
        self.setup_upload_tab(upload_tab)
        self.setup_query_tab(query_tab)
        self.setup_stats_tab(stats_tab)

    def set_style(self):
        # 设置应用程序样式
        app = QApplication.instance()
        app.setStyle("Fusion")

        # 设置全局调色板
        palette = QPalette()
        palette.setColor(QPalette.Window, QColor(240, 240, 240))
        palette.setColor(QPalette.WindowText, QColor(0, 0, 0))
        palette.setColor(QPalette.Base, QColor(255, 255, 255))
        palette.setColor(QPalette.AlternateBase, QColor(245, 245, 245))
        palette.setColor(QPalette.ToolTipBase, QColor(255, 255, 220))
        palette.setColor(QPalette.ToolTipText, QColor(0, 0, 0))
        palette.setColor(QPalette.Text, QColor(0, 0, 0))
        palette.setColor(QPalette.Button, QColor(240, 240, 240))
        palette.setColor(QPalette.ButtonText, QColor(0, 0, 0))
        palette.setColor(QPalette.BrightText, QColor(255, 0, 0))
        palette.setColor(QPalette.Highlight, QColor(42, 130, 218))
        palette.setColor(QPalette.HighlightedText, QColor(255, 255, 255))
        app.setPalette(palette)

        # 设置按钮样式
        self.button_style = """
            QPushButton {
                background-color: #2980b9;
                color: white;
                border: 1px solid #2980b9;
                border-radius: 4px;
                padding: 5px 10px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #3498db;
                border: 1px solid #3498db;
            }
            QPushButton:pressed {
                background-color: #1c6ea4;
                border: 1px solid #1c6ea4;
            }
        """

        # 设置表格样式
        self.table_style = """
            QTableWidget {
                gridline-color: #d9d9d9;
                selection-background-color: #e6f3ff;
                selection-color: black;
            }
            QHeaderView::section {
                background-color: #f0f0f0;
                padding: 4px;
                border: 1px solid #d9d9d9;
                font-weight: bold;
            }
        """

        # 设置分组框样式
        self.group_style = """
            QGroupBox {
                border: 1px solid #cccccc;
                border-radius: 5px;
                margin-top: 1ex;
                font-weight: bold;
            }
            QGroupBox::title {
                subcontrol-origin: margin;
                subcontrol-position: top center;
                padding: 0 3px;
            }
        """

    def setup_upload_tab(self, tab):
        # 创建上传页面布局
        layout = QVBoxLayout(tab)

        # 创建上传区域
        upload_group = QGroupBox("发票上传")
        upload_group.setStyleSheet(self.group_style)
        upload_layout = QVBoxLayout()
        upload_group.setLayout(upload_layout)

        # 文件选择和上传按钮
        file_layout = QHBoxLayout()
        self.file_path_label = QLineEdit()
        self.file_path_label.setReadOnly(True)
        self.file_path_label.setPlaceholderText("请选择发票图片文件...")
        browse_button = QPushButton("浏览")
        browse_button.setStyleSheet(self.button_style)
        browse_button.clicked.connect(self.browse_file)
        upload_button = QPushButton("上传并识别")
        upload_button.setStyleSheet(self.button_style)
        upload_button.clicked.connect(self.upload_invoice)

        file_layout.addWidget(self.file_path_label)
        file_layout.addWidget(browse_button)
        file_layout.addWidget(upload_button)
        upload_layout.addLayout(file_layout)

        # 进度条
        self.progress_bar = QProgressBar()
        self.progress_bar.setVisible(False)
        upload_layout.addWidget(self.progress_bar)

        # 发票预览和信息区域
        preview_info_layout = QHBoxLayout()

        # 发票预览
        preview_group = QGroupBox("发票预览")
        preview_group.setStyleSheet(self.group_style)
        preview_layout = QVBoxLayout()
        preview_group.setLayout(preview_layout)

        self.preview_label = QLabel()
        self.preview_label.setAlignment(Qt.AlignCenter)
        self.preview_label.setMinimumSize(400, 300)
        self.preview_label.setFrameShape(QFrame.StyledPanel)
        self.preview_label.setText("发票图片预览区域")
        preview_layout.addWidget(self.preview_label)

        # 发票信息
        info_group = QGroupBox("发票信息")
        info_group.setStyleSheet(self.group_style)
        info_layout = QFormLayout()
        info_group.setLayout(info_layout)

        self.invoice_number_edit = QLineEdit()
        self.invoice_date_edit = QDateEdit()
        self.invoice_date_edit.setCalendarPopup(True)
        self.invoice_date_edit.setDate(QDate.currentDate())
        self.seller_name_edit = QLineEdit()
        self.purchaser_name_edit = QLineEdit()
        self.item_name_edit = QLineEdit()
        self.amount_without_tax_edit = QLineEdit()
        self.tax_edit = QLineEdit()
        self.amount_with_tax_edit = QLineEdit()

        info_layout.addRow("发票号码:", self.invoice_number_edit)
        info_layout.addRow("开票日期:", self.invoice_date_edit)
        info_layout.addRow("销售方名称:", self.seller_name_edit)
        info_layout.addRow("购买方名称:", self.purchaser_name_edit)
        info_layout.addRow("项目名称:", self.item_name_edit)
        info_layout.addRow("不含税金额:", self.amount_without_tax_edit)
        info_layout.addRow("税额:", self.tax_edit)
        info_layout.addRow("含税金额:", self.amount_with_tax_edit)

        preview_info_layout.addWidget(preview_group, 1)
        preview_info_layout.addWidget(info_group, 1)

        # 保存按钮
        save_layout = QHBoxLayout()
        save_button = QPushButton("保存发票信息")
        save_button.setStyleSheet(self.button_style)
        save_button.clicked.connect(self.save_invoice)
        clear_button = QPushButton("清除")
        clear_button.setStyleSheet("""
            QPushButton {
                background-color: #e74c3c;
                color: white;
                border: 1px solid #e74c3c;
                border-radius: 4px;
                padding: 5px 10px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #c0392b;
                border: 1px solid #c0392b;
            }
        """)
        clear_button.clicked.connect(self.clear_upload_form)

        save_layout.addStretch()
        save_layout.addWidget(clear_button)
        save_layout.addWidget(save_button)

        # 添加所有组件到上传页面布局
        layout.addWidget(upload_group)
        layout.addLayout(preview_info_layout)
        layout.addLayout(save_layout)

    def setup_query_tab(self, tab):
        # 创建查询页面布局
        layout = QVBoxLayout(tab)

        # 创建查询条件区域
        query_group = QGroupBox("查询条件")
        query_group.setStyleSheet(self.group_style)
        query_layout = QHBoxLayout()
        query_group.setLayout(query_layout)

        # 日期范围
        date_layout = QHBoxLayout()
        date_layout.addWidget(QLabel("日期范围:"))
        self.start_date_edit = QDateEdit()
        self.start_date_edit.setCalendarPopup(True)
        self.start_date_edit.setDate(QDate.currentDate().addMonths(-1))
        date_layout.addWidget(self.start_date_edit)
        date_layout.addWidget(QLabel("至"))
        self.end_date_edit = QDateEdit()
        self.end_date_edit.setCalendarPopup(True)
        self.end_date_edit.setDate(QDate.currentDate())
        date_layout.addWidget(self.end_date_edit)

        # 关键字搜索
        keyword_layout = QHBoxLayout()
        keyword_layout.addWidget(QLabel("关键字:"))
        self.keyword_edit = QLineEdit()
        self.keyword_edit.setPlaceholderText("输入关键字进行模糊搜索...")
        keyword_layout.addWidget(self.keyword_edit)

        # 搜索字段选择
        self.search_field_combo = QComboBox()
        self.search_field_combo.addItems(["全部字段", "发票号码", "销售方", "购买方", "项目名称"])
        keyword_layout.addWidget(self.search_field_combo)

        # 搜索按钮
        search_button = QPushButton("搜索")
        search_button.setStyleSheet(self.button_style)
        search_button.clicked.connect(self.search_invoices)
        reset_button = QPushButton("重置")
        reset_button.clicked.connect(self.reset_search)

        # 添加所有查询条件到布局
        query_layout.addLayout(date_layout)
        query_layout.addLayout(keyword_layout)
        query_layout.addWidget(search_button)
        query_layout.addWidget(reset_button)

        # 创建查询结果显示区域
        results_splitter = QSplitter(Qt.Vertical)

        # 结果表格
        self.results_table = QTableWidget()
        self.results_table.setStyleSheet(self.table_style)
        self.results_table.setColumnCount(9)
        self.results_table.setHorizontalHeaderLabels([
            "发票号码", "开票日期", "销售方名称", "购买方名称",
            "项目名称", "不含税金额", "税额", "含税金额", "上传日期"
        ])
        header = self.results_table.horizontalHeader()
        header.setSectionResizeMode(QHeaderView.Stretch)
        self.results_table.clicked.connect(self.show_invoice_image)

        # 发票图片预览
        image_preview_group = QGroupBox("发票图片预览")
        image_preview_group.setStyleSheet(self.group_style)
        image_preview_layout = QVBoxLayout()
        image_preview_group.setLayout(image_preview_layout)

        self.image_preview_label = QLabel()
        self.image_preview_label.setAlignment(Qt.AlignCenter)
        self.image_preview_label.setMinimumHeight(300)
        self.image_preview_label.setText("选择发票记录查看图片")
        self.image_preview_label.setFrameShape(QFrame.StyledPanel)
        image_preview_layout.addWidget(self.image_preview_label)

        # 添加组件到分割器
        results_splitter.addWidget(self.results_table)
        results_splitter.addWidget(image_preview_group)
        results_splitter.setSizes([500, 300])

        # 添加组件到查询页面布局
        layout.addWidget(query_group)
        layout.addWidget(results_splitter)

    def setup_stats_tab(self, tab):
        # 创建统计页面布局
        layout = QVBoxLayout(tab)

        # 创建统计条件区域
        stats_group = QGroupBox("统计条件")
        stats_group.setStyleSheet(self.group_style)
        stats_layout = QHBoxLayout()
        stats_group.setLayout(stats_layout)

        # 日期范围
        date_layout = QHBoxLayout()
        date_layout.addWidget(QLabel("日期范围:"))
        self.stats_start_date_edit = QDateEdit()
        self.stats_start_date_edit.setCalendarPopup(True)
        self.stats_start_date_edit.setDate(QDate.currentDate().addMonths(-1))
        date_layout.addWidget(self.stats_start_date_edit)
        date_layout.addWidget(QLabel("至"))
        self.stats_end_date_edit = QDateEdit()
        self.stats_end_date_edit.setCalendarPopup(True)
        self.stats_end_date_edit.setDate(QDate.currentDate())
        date_layout.addWidget(self.stats_end_date_edit)

        # 关键字筛选
        keyword_layout = QHBoxLayout()
        keyword_layout.addWidget(QLabel("关键字:"))
        self.stats_keyword_edit = QLineEdit()
        self.stats_keyword_edit.setPlaceholderText("输入关键字进行模糊筛选...")
        keyword_layout.addWidget(self.stats_keyword_edit)

        # 筛选字段选择
        self.stats_field_combo = QComboBox()
        self.stats_field_combo.addItems(["全部字段", "销售方", "购买方", "项目名称"])
        keyword_layout.addWidget(self.stats_field_combo)

        # 统计按钮
        stats_button = QPushButton("统计")
        stats_button.setStyleSheet(self.button_style)
        stats_button.clicked.connect(self.calculate_stats)

        # 添加所有统计条件到布局
        stats_layout.addLayout(date_layout)
        stats_layout.addLayout(keyword_layout)
        stats_layout.addWidget(stats_button)

        # 创建统计结果显示区域
        stats_results_group = QGroupBox("统计结果")
        stats_results_group.setStyleSheet(self.group_style)
        stats_results_layout = QVBoxLayout()
        stats_results_group.setLayout(stats_results_layout)

        # 汇总信息
        summary_layout = QHBoxLayout()

        total_count_group = QGroupBox("发票总数")
        total_count_layout = QVBoxLayout()
        self.total_count_label = QLabel("0")
        self.total_count_label.setAlignment(Qt.AlignCenter)
        self.total_count_label.setFont(QFont("Arial", 24, QFont.Bold))
        total_count_layout.addWidget(self.total_count_label)
        total_count_group.setLayout(total_count_layout)

        total_amount_group = QGroupBox("金额总计(含税)")
        total_amount_layout = QVBoxLayout()
        self.total_amount_label = QLabel("¥0.00")
        self.total_amount_label.setAlignment(Qt.AlignCenter)
        self.total_amount_label.setFont(QFont("Arial", 24, QFont.Bold))
        total_amount_layout.addWidget(self.total_amount_label)
        total_amount_group.setLayout(total_amount_layout)

        tax_amount_group = QGroupBox("税额总计")
        tax_amount_layout = QVBoxLayout()
        self.tax_amount_label = QLabel("¥0.00")
        self.tax_amount_label.setAlignment(Qt.AlignCenter)
        self.tax_amount_label.setFont(QFont("Arial", 24, QFont.Bold))
        tax_amount_layout.addWidget(self.tax_amount_label)
        tax_amount_group.setLayout(tax_amount_layout)

        summary_layout.addWidget(total_count_group)
        summary_layout.addWidget(total_amount_group)
        summary_layout.addWidget(tax_amount_group)

        # 明细表格
        self.stats_table = QTableWidget()
        self.stats_table.setStyleSheet(self.table_style)
        self.stats_table.setColumnCount(4)
        self.stats_table.setHorizontalHeaderLabels([
            "分类", "发票数量", "金额总计(含税)", "税额总计"
        ])
        header = self.stats_table.horizontalHeader()
        header.setSectionResizeMode(QHeaderView.Stretch)

        # 添加组件到统计结果布局
        stats_results_layout.addLayout(summary_layout)
        stats_results_layout.addWidget(self.stats_table)

        # 添加组件到统计页面布局
        layout.addWidget(stats_group)
        layout.addWidget(stats_results_group)

    def browse_file(self):
        file_path, _ = QFileDialog.getOpenFileName(
            self, "选择发票图片", "", "图片文件 (*.png *.jpg *.jpeg *.bmp)"
        )
        if file_path:
            self.file_path_label.setText(file_path)

            # 显示图片预览
            pixmap = QPixmap(file_path)
            if not pixmap.isNull():
                pixmap = pixmap.scaled(400, 300, Qt.KeepAspectRatio, Qt.SmoothTransformation)
                self.preview_label.setPixmap(pixmap)
            else:
                self.preview_label.setText("无法加载图片")

    def upload_invoice(self):
        file_path = self.file_path_label.text()
        if not file_path:
            QMessageBox.warning(self, "提示", "请先选择发票图片文件")
            return

        try:
            # 显示进度条
            self.progress_bar.setVisible(True)
            self.progress_bar.setValue(20)

            # 读取图片文件
            with open(file_path, 'rb') as f:
                img = base64.b64encode(f.read())

            self.progress_bar.setValue(40)

            # 调用百度OCR API
            params = {"image": img}
            request_url = OCR_API_URL + "?access_token=" + OCR_API_TOKEN
            headers = {'content-type': 'application/x-www-form-urlencoded'}

            response = requests.post(request_url, data=params, headers=headers)

            self.progress_bar.setValue(80)

            if response.status_code == 200:
                response_json = response.json()

                # 解析发票信息
                if 'words_result' in response_json:
                    result = response_json['words_result']

                    # 填充表单
                    self.invoice_number_edit.setText(result.get("InvoiceNum", ""))

                    # 处理日期格式
                    invoice_date_str = result.get("InvoiceDate", "")
                    if invoice_date_str:
                        # 转换中文日期格式 (例如: "2025年02月04日" -> "2025-02-04")
                        date_parts = invoice_date_str.replace('年', '-').replace('月', '-').replace('日', '')
                        try:
                            date_obj = datetime.datetime.strptime(date_parts, "%Y-%m-%d")
                            self.invoice_date_edit.setDate(QDate(date_obj.year, date_obj.month, date_obj.day))
                        except ValueError:
                            self.invoice_date_edit.setDate(QDate.currentDate())

                    self.seller_name_edit.setText(result.get("SellerName", ""))
                    self.purchaser_name_edit.setText(result.get("PurchaserName", ""))

                    # 处理项目名称
                    if "CommodityName" in result and result["CommodityName"]:
                        self.item_name_edit.setText(result["CommodityName"][0]["word"])

                    self.amount_without_tax_edit.setText(result.get("TotalAmount", ""))
                    self.tax_edit.setText(result.get("TotalTax", ""))
                    self.amount_with_tax_edit.setText(result.get("AmountInFiguers", ""))

                    QMessageBox.information(self, "成功", "发票识别成功")
                else:
                    QMessageBox.warning(self, "错误", "无法识别发票内容")
            else:
                QMessageBox.warning(self, "错误", f"API调用失败: {response.status_code}")

        except Exception as e:
            QMessageBox.critical(self, "错误", f"上传过程中出错: {str(e)}")

        finally:
            self.progress_bar.setValue(100)
            self.progress_bar.setVisible(False)

    def save_invoice(self):
        # 检查数据库连接
        if not hasattr(self, 'db_connected') or not self.db_connected:
            QMessageBox.warning(self, "数据库错误", "数据库未连接，无法保存数据")
            return

        # 获取表单数据
        invoice_number = self.invoice_number_edit.text()
        invoice_date = self.invoice_date_edit.date().toString("yyyy-MM-dd")
        seller_name = self.seller_name_edit.text()
        purchaser_name = self.purchaser_name_edit.text()
        item_name = self.item_name_edit.text()

        try:
            amount_without_tax = float(self.amount_without_tax_edit.text())
            tax = float(self.tax_edit.text())
            amount_with_tax = float(self.amount_with_tax_edit.text())
        except ValueError:
            QMessageBox.warning(self, "错误", "金额和税额必须是有效数字")
            return

        # 验证必填字段
        if not invoice_number or not seller_name:
            QMessageBox.warning(self, "错误", "发票号码和销售方名称为必填项")
            return

        # 获取图片路径
        file_path = self.file_path_label.text()
        if not file_path:
            QMessageBox.warning(self, "错误", "请先选择发票图片")
            return

        try:
            # 创建存储目录
            storage_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "invoice_images")
            os.makedirs(storage_dir, exist_ok=True)

            # 复制图片到存储目录
            file_ext = os.path.splitext(file_path)[1]
            new_file_name = f"{invoice_number}{file_ext}"
            new_file_path = os.path.join(storage_dir, new_file_name)

            with open(file_path, 'rb') as src_file, open(new_file_path, 'wb') as dst_file:
                dst_file.write(src_file.read())

            # 保存到数据库
            try:
                self.cursor.execute('''
                    INSERT INTO invoices (
                        invoice_number, invoice_date, seller_name, purchaser_name,
                        item_name, amount_without_tax, tax, amount_with_tax, image_path
                    ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
                ''', (
                    invoice_number, invoice_date, seller_name, purchaser_name,
                    item_name, amount_without_tax, tax, amount_with_tax, new_file_path
                ))
                self.conn.commit()
                QMessageBox.information(self, "成功", "发票信息保存成功")
                self.clear_upload_form()

            except Error as e:
                if e.errno == 1062:  # 重复键错误
                    QMessageBox.warning(self, "错误", "该发票号码已存在")
                else:
                    QMessageBox.critical(self, "数据库错误", f"保存发票信息时出错: {e}")

        except Exception as e:
            QMessageBox.critical(self, "错误", f"保存发票时出错: {str(e)}")

    def clear_upload_form(self):
        self.file_path_label.clear()
        self.preview_label.setText("发票图片预览区域")
        self.invoice_number_edit.clear()
        self.invoice_date_edit.setDate(QDate.currentDate())
        self.seller_name_edit.clear()
        self.purchaser_name_edit.clear()
        self.item_name_edit.clear()
        self.amount_without_tax_edit.clear()
        self.tax_edit.clear()
        self.amount_with_tax_edit.clear()

    def search_invoices(self):
        # 检查数据库连接
        if not hasattr(self, 'db_connected') or not self.db_connected:
            QMessageBox.warning(self, "数据库错误", "数据库未连接，无法执行查询")
            return

        start_date = self.start_date_edit.date().toString("yyyy-MM-dd")
        end_date = self.end_date_edit.date().toString("yyyy-MM-dd")
        keyword = self.keyword_edit.text()
        search_field = self.search_field_combo.currentText()

        # 构建查询
        query = '''
            SELECT 
                invoice_number, invoice_date, seller_name, purchaser_name,
                item_name, amount_without_tax, tax, amount_with_tax, upload_date,
                image_path
            FROM invoices
            WHERE invoice_date BETWEEN %s AND %s
        '''

        params = [start_date, end_date]

        # 添加关键字搜索条件
        if keyword:
            if search_field == "全部字段":
                query += '''
                    AND (
                        invoice_number LIKE %s OR
                        seller_name LIKE %s OR
                        purchaser_name LIKE %s OR
                        item_name LIKE %s
                    )
                '''
                keyword_param = f"%{keyword}%"
                params.extend([keyword_param, keyword_param, keyword_param, keyword_param])
            elif search_field == "发票号码":
                query += " AND invoice_number LIKE %s"
                params.append(f"%{keyword}%")
            elif search_field == "销售方":
                query += " AND seller_name LIKE %s"
                params.append(f"%{keyword}%")
            elif search_field == "购买方":
                query += " AND purchaser_name LIKE %s"
                params.append(f"%{keyword}%")
            elif search_field == "项目名称":
                query += " AND item_name LIKE %s"
                params.append(f"%{keyword}%")

        # 执行查询
        try:
            self.cursor.execute(query, params)
            results = self.cursor.fetchall()

            # 清空表格
            self.results_table.setRowCount(0)

            # 存储图片路径
            self.invoice_images = {}

            # 填充表格
            for row_idx, row_data in enumerate(results):
                self.results_table.insertRow(row_idx)

                # 存储图片路径
                self.invoice_images[row_idx] = row_data[9]

                # 设置表格数据（除图片路径外）
                for col_idx, col_data in enumerate(row_data[:9]):
                    item = QTableWidgetItem(str(col_data))
                    self.results_table.setItem(row_idx, col_idx, item)

            # 显示结果计数
            if results:
                QMessageBox.information(self, "搜索结果", f"找到 {len(results)} 条发票记录")
            else:
                QMessageBox.information(self, "搜索结果", "未找到符合条件的发票记录")

        except Error as e:
            QMessageBox.critical(self, "数据库错误", f"查询发票时出错: {e}")

    def reset_search(self):
        # 重置查询条件
        self.start_date_edit.setDate(QDate.currentDate().addMonths(-1))
        self.end_date_edit.setDate(QDate.currentDate())
        self.keyword_edit.clear()
        self.search_field_combo.setCurrentIndex(0)

        # 清空表格和预览
        self.results_table.setRowCount(0)
        self.image_preview_label.setText("选择发票记录查看图片")

    def show_invoice_image(self, index):
        row = index.row()

        if row in self.invoice_images:
            image_path = self.invoice_images[row]

            # 显示图片
            pixmap = QPixmap(image_path)
            if not pixmap.isNull():
                pixmap = pixmap.scaled(
                    self.image_preview_label.width(),
                    self.image_preview_label.height(),
                    Qt.KeepAspectRatio,
                    Qt.SmoothTransformation
                )
                self.image_preview_label.setPixmap(pixmap)
            else:
                self.image_preview_label.setText("无法加载图片")

    def calculate_stats(self):
        # 检查数据库连接
        if not hasattr(self, 'db_connected') or not self.db_connected:
            QMessageBox.warning(self, "数据库错误", "数据库未连接，无法执行统计")
            return

        start_date = self.stats_start_date_edit.date().toString("yyyy-MM-dd")
        end_date = self.stats_end_date_edit.date().toString("yyyy-MM-dd")
        keyword = self.stats_keyword_edit.text()
        filter_field = self.stats_field_combo.currentText()

        # 构建查询 - 总计
        query = '''
            SELECT 
                COUNT(*) as total_count,
                SUM(amount_with_tax) as total_amount,
                SUM(tax) as total_tax
            FROM invoices
            WHERE invoice_date BETWEEN %s AND %s
        '''

        params = [start_date, end_date]

        # 添加关键字过滤条件
        if keyword:
            if filter_field == "全部字段":
                query += '''
                    AND (
                        seller_name LIKE %s OR
                        purchaser_name LIKE %s OR
                        item_name LIKE %s
                    )
                '''
                keyword_param = f"%{keyword}%"
                params.extend([keyword_param, keyword_param, keyword_param])
            elif filter_field == "销售方":
                query += " AND seller_name LIKE %s"
                params.append(f"%{keyword}%")
            elif filter_field == "购买方":
                query += " AND purchaser_name LIKE %s"
                params.append(f"%{keyword}%")
            elif filter_field == "项目名称":
                query += " AND item_name LIKE %s"
                params.append(f"%{keyword}%")

        try:
            # 执行总计查询
            self.cursor.execute(query, params)
            summary = self.cursor.fetchone()

            total_count = summary[0] or 0
            total_amount = summary[1] or 0
            total_tax = summary[2] or 0

            # 更新总计显示
            self.total_count_label.setText(str(total_count))
            self.total_amount_label.setText(f"¥{total_amount:.2f}")
            self.tax_amount_label.setText(f"¥{total_tax:.2f}")

            # 根据筛选字段进行分组统计
            if filter_field == "全部字段" or filter_field == "销售方":
                self.calculate_group_stats("seller_name", "销售方", start_date, end_date, keyword, filter_field)
            elif filter_field == "购买方":
                self.calculate_group_stats("purchaser_name", "购买方", start_date, end_date, keyword, filter_field)
            elif filter_field == "项目名称":
                self.calculate_group_stats("item_name", "项目", start_date, end_date, keyword, filter_field)

        except Error as e:
            QMessageBox.critical(self, "数据库错误", f"统计发票时出错: {e}")

    def calculate_group_stats(self, group_field, group_label, start_date, end_date, keyword, filter_field):
        # 构建分组查询
        query = f'''
            SELECT 
                {group_field} as group_name,
                COUNT(*) as count,
                SUM(amount_with_tax) as total_amount,
                SUM(tax) as total_tax
            FROM invoices
            WHERE invoice_date BETWEEN %s AND %s
        '''

        params = [start_date, end_date]

        # 添加关键字过滤条件
        if keyword:
            if filter_field == "全部字段":
                query += '''
                    AND (
                        seller_name LIKE %s OR
                        purchaser_name LIKE %s OR
                        item_name LIKE %s
                    )
                '''
                keyword_param = f"%{keyword}%"
                params.extend([keyword_param, keyword_param, keyword_param])
            elif filter_field == "销售方":
                query += " AND seller_name LIKE %s"
                params.append(f"%{keyword}%")
            elif filter_field == "购买方":
                query += " AND purchaser_name LIKE %s"
                params.append(f"%{keyword}%")
            elif filter_field == "项目名称":
                query += " AND item_name LIKE %s"
                params.append(f"%{keyword}%")

        query += f" GROUP BY {group_field} ORDER BY count DESC"

        try:
            # 执行分组查询
            self.cursor.execute(query, params)
            results = self.cursor.fetchall()

            # 清空表格
            self.stats_table.setRowCount(0)

            # 填充表格
            for row_idx, (group_name, count, amount, tax) in enumerate(results):
                self.stats_table.insertRow(row_idx)

                self.stats_table.setItem(row_idx, 0, QTableWidgetItem(str(group_name)))
                self.stats_table.setItem(row_idx, 1, QTableWidgetItem(str(count)))
                self.stats_table.setItem(row_idx, 2, QTableWidgetItem(f"¥{amount:.2f}"))
                self.stats_table.setItem(row_idx, 3, QTableWidgetItem(f"¥{tax:.2f}"))

        except Error as e:
            QMessageBox.critical(self, "数据库错误", f"统计发票分组时出错: {e}")


def main():
    app = QApplication(sys.argv)
    print("App started")
    window = InvoiceSystem()
    print("Window created")
    window.show()
    print("Window shown")
    sys.exit(app.exec_())
    print("App exited")  # 这行代码不会执行到，因为sys.exit()已经终止了程序


if __name__ == "__main__":
    main()